package org.kimoji.security.tool;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;

public class SecurityTool {

	private static final String PWD = "!QA@WS#ED$RF%TGl";
	private static final String IV = "MNBVCXZlkjhgfdsa";

	public static String md5(String value) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			byte[] bytes = value.getBytes();
			MessageDigest messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.update(bytes);
			byte[] updateBytes = messageDigest.digest();
			int len = updateBytes.length;
			char myChar[] = new char[len * 2];
			
			int k = 0;
			for (int i = 0; i < len; i++) {
				byte byte0 = updateBytes[i];
				myChar[k++] = hexDigits[byte0 >>> 4 & 0x0f];
				myChar[k++] = hexDigits[byte0 & 0x0f];
			}
			return new String(myChar);
		} catch (Exception e) {
			return null;
		}
	}

	public static String AESEncrypt(String value) {
		try {
			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, key(), iv());
			byte[] byteValue = cipher.doFinal(value.getBytes("utf-8"));
			return parseByte2HexStr(byteValue);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String AESDecrypt(String value) {
		try {
			
			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, key(), iv());
			byte[] byteValue = cipher.doFinal(parseHexStr2Byte(value));
			return new String(byteValue);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;

	}

	public static SecretKeySpec key() throws NoSuchAlgorithmException, UnsupportedEncodingException, DecoderException {
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		kgen.init(128, new SecureRandom(PWD.getBytes("UTF-8")));
		SecretKey key = kgen.generateKey();
		SecretKeySpec keySpec = new SecretKeySpec(key.getEncoded(), "AES");
		// SecretKeySpec keySpec = new SecretKeySpec(PWD.getBytes("UTF-8"),
		// "AES");
		return keySpec;
	}

	public static IvParameterSpec iv() throws UnsupportedEncodingException, DecoderException {
		return new IvParameterSpec(IV.getBytes("UTF-8"));
	}

	public static String parseByte2HexStr(byte buf[]) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < buf.length; i++) {
			String hex = Integer.toHexString(buf[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex.toUpperCase());
		}
		return sb.toString();
	}

	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}
	
}
